<script setup>
import { ref, reactive, onMounted, inject } from "vue"
import { Base64 } from "js-base64"
import copyw from "@/components/copy.vue"
import pako from "pako"
import useClipboard from "vue-clipboard3"
import { message } from "ant-design-vue"

const globalVars = inject("globalVars")

const { toClipboard } = useClipboard()
const state = reactive({
    sourceValue: "",
    encodeData: "",
    decodeData: "",
    checked: false,
})
function Utf8ArrayToStr(array) {
    var out, i, len, c
    var char2, char3

    out = ""
    len = array.length
    i = 0
    while (i < len) {
        c = array[i++]
        switch (c >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c)
                break
            case 12:
            case 13:
                // 110x xxxx   10xx xxxx
                char2 = array[i++]
                out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f))
                break
            case 14:
                // 1110 xxxx  10xx xxxx  10xx xxxx
                char2 = array[i++]
                char3 = array[i++]
                out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0))
                break
        }
    }

    return out
}

const copy = async (msg) => {
    try {
        // 复制
        await toClipboard(msg)
        message.success("复制成功")
        // 复制成功
    } catch (e) {
        // 复制失败
    }
}

function gdecode(encodedData) {
    // 先 base64编码
    let binData = Base64.toUint8Array(encodedData)

    let data = pako.inflate(binData)
    //接受 Unicode 值，然后返回字符串。
    let decodedData = Utf8ArrayToStr(data)
    return decodedData
}
function gencode(v) {
    let binaryString = pako.gzip(v)
    return Base64.fromUint8Array(binaryString)
}

function bencode() {
    if (state.checked) {
        state.encodeData = gencode(state.sourceValue)
        return
    }
    state.encodeData = Base64.encode(state.sourceValue)
}

function bdecode() {
    state.platformValue = ""
    try {
        if (state.checked) {
            state.decodeData = gdecode(state.sourceValue)
            return
        }
        state.decodeData = Base64.decode(state.sourceValue)
    } catch (error) {
        console.log(error)
        // message.error("解码失败,请检查原数据")
        state.decodeData = "解码失败,请检查原数据"
    }
}
function change() {
    localStorage.setItem(globalVars.activeKey, state.sourceValue)
    if (state.sourceValue === "") {
        state.encodeData = ""
        state.decodeData = ""
        return
    }
    bdecode()
    bencode()
}

onMounted(() => {
    let c = localStorage.getItem(globalVars.activeKey)
    if (c) {
        state.sourceValue = c
    }
    change()
})
</script>

<template>
    <div class="k f">
        <div class="content f_col">
            <h1 class="f_row" style="justify-content: flex-start">
                Base64转换<copyw title="Base64转换" ckey="dobase64"></copyw>
            </h1>
            <div style="width: 100%">
                <div class="f_row" style="justify-content: flex-start">
                    <h3>源码</h3>
                    <a-checkbox
                        v-model:checked="state.checked"
                        style="margin-left: 8px; margin-bottom: 8px; color: var(--character-85)"
                        @change="change"
                        >gzip</a-checkbox
                    >
                </div>

                <a-textarea
                    class="kuang"
                    v-model:value="state.sourceValue"
                    allow-clear
                    show-count
                    placeholder="原码"
                    :auto-size="{ minRows: 6, maxRows: 15 }"
                    @change="change"
                    autofocus
                />
            </div>
            <div style="width: 100%">
                <div class="f_row" style="justify-content: flex-start">
                    <h3>编码</h3>
                    <a style="margin-bottom: 8px; margin-left: 12px; cursor: pointer" @click="copy(state.encodeData)"
                        >复制</a
                    >
                </div>
                <div v-text="state.encodeData" class="auto-wrap"></div>
            </div>
            <div style="width: 100%">
                <div class="f_row" style="justify-content: flex-start">
                    <h3>解码</h3>
                    <a style="margin-bottom: 8px; margin-left: 12px; cursor: pointer" @click="copy(state.decodeData)"
                        >复制</a
                    >
                </div>

                <div v-text="state.decodeData" class="auto-wrap"></div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.content {
    max-width: 860px;
    width: 100%;
    margin: 0 auto;
    padding: 32px;
    gap: 24px;
    align-items: flex-start;
    min-height: calc(100vh - 66px);
    justify-content: flex-start;
    background-color: var(--Neutral-12);
    border-radius: 12px;
    border: 1px solid var(--Neutral-10);
}

:where(.k) {
    background-color: var(--page-bg-color);
    height: 100%;
    padding: 16px;
}

h1 {
    color: var(--character-85);
    font-size: 24px;
    margin-bottom: 8px;
}

h3 {
    color: var(--character-75);
    font-size: 16px;
    margin-bottom: 8px;
}

.auto-wrap {
    background-color: var(--Neutral-11);
    padding: 12px 16px;
    border-radius: 8px;
    border: 1px solid var(--Neutral-10);
    color: var(--character-85);
    min-height: 48px;
}

:deep(.ant-textarea) {
    background-color: var(--Neutral-11) !important;
    border: 1px solid var(--Neutral-10) !important;
    color: var(--character-85) !important;
    border-radius: 8px;
    transition: all 0.3s ease;
}

:deep(.ant-textarea:hover) {
    border-color: var(--Neutral-9) !important;
}

:deep(.ant-textarea:focus) {
    border-color: var(--Neutral-8) !important;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.05);
}

a {
    color: var(--Geek-Blue-5);
    transition: color 0.3s ease;
}

a:hover {
    color: var(--Geek-Blue-4);
}

:deep(.ant-checkbox) {
    color: var(--character-85) !important;
}

:deep(.ant-checkbox-checked .ant-checkbox-inner) {
    background-color: var(--Geek-Blue-5) !important;
    border-color: var(--Geek-Blue-5) !important;
}

:deep(.ant-checkbox-wrapper:hover .ant-checkbox-inner),
:deep(.ant-checkbox:hover .ant-checkbox-inner) {
    border-color: var(--Geek-Blue-4) !important;
}
</style>
